package com.sand.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sand.Exception.SandException;
import com.sand.dto.Owner.signSelect;
import com.sand.dto.Select.UserSelect;
import com.sand.dto.Shopping.AddShoppingDto;
import com.sand.dto.Shopping.SelectShoppingDto;
import com.sand.dto.supplier.SupplierDto;
import com.sand.entity.inventory.inventory;
import com.sand.entity.shopping.shopping;
import com.sand.feign.inventoryFeign;
import com.sand.feign.merchantFeign;
import com.sand.feign.supplierFeign;
import com.sand.mapper.ShoppingMapper;
import com.sand.merchant.Permission;
import com.sand.result.AppHttpCodeEnum;
import com.sand.service.ShoppingService;
import com.sand.user.UserStatus;
import com.sand.user.UserType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Service
public class ShoppingServiceImpl extends ServiceImpl<ShoppingMapper, shopping> implements ShoppingService {

    @Autowired
    private merchantFeign merchantFeign;

    @Autowired
    private inventoryFeign inventoryFeign;

    @Autowired
    private ShoppingMapper shoppingMapper;

    @Autowired
    private supplierFeign supplierFeign;

    /**
     * 新增或修改商品
     *
     * @param addShoppingDto
     * @return
     */
    @Override
    public String add(AddShoppingDto addShoppingDto) {

        //参数校验
        jiaoyan(addShoppingDto);

        //获取当前操作人
        Integer id = addShoppingDto.getCid();

        //获取当前操作人的权限
        Integer i = merchantFeign.permission(id).getData();

        //操作人权限判断
        if (i == null || i.equals(Permission.NO)){
            throw new SandException(AppHttpCodeEnum.NEED_ADMIND,"当前操作人权限不够");
        }

        //判断是什么操作
        if (addShoppingDto.getId() == null){
            //判断是否有对应的库存

            //存在,该商品存在无法新增
            shopping one = getOne(new LambdaQueryWrapper<shopping>().eq(shopping::getName, addShoppingDto.getName()));

            if (one != null){
                throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"该商品已经存在无法添加");
            }

            //字段校验
            pan(addShoppingDto);

            //判断供货商是否存在并且供货商状态良好
            panSupp(addShoppingDto);

            shopping shopping = new shopping();
            BeanUtils.copyProperties(addShoppingDto,shopping);

            //不存在,添加商品
            save(shopping);

            //创建库存
            inventory inventory = new inventory();
            inventory.setShoppingId(shopping.getId());
            inventory.setAmount(1);
            inventoryFeign.add(inventory);

            return "新增商品成功";
        }

        //判断是否存在商品
        shopping shopping = getById(addShoppingDto.getId());

        if (shopping == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"当前商品不存在");
        }

        //字段校验
        pan(addShoppingDto);

        panSupp(addShoppingDto);

        shopping s = new shopping();
        BeanUtils.copyProperties(addShoppingDto,s);

        try {
            updateById(s);
        } catch (Exception e) {
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"修改商品失败,商品名称重复");
        }

        return "修改商品成功";
    }
    
    private void panSupp(AddShoppingDto addShoppingDto) {
        //判断供货商是否存在并且供货商状态良好
        SupplierDto supplierDto = supplierFeign.select(new UserSelect(addShoppingDto.getSource(), "")).getData();

        if (supplierDto == null || supplierDto.getType() != UserType.SUPPLIER){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"传入的用户不存在或不是供货商");
        }

        if (supplierDto.getStatus() == UserStatus.NO_EXIST){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"当前供货商暂时停止供货");
        }
    }


    /**
     * 根据id查询商品信息
     *
     * @param
     * @return
     */
    @Override
    public ArrayList<shopping> select(Integer[] ids) {

        ArrayList<Integer> list = new ArrayList<>(Arrays.asList(ids));

        ArrayList<shopping> shoppingList = (ArrayList<shopping>) shoppingMapper.selectBatchIds(list);

        if (list.size() != shoppingList.size()){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"传递的商品id存在有误");
        }

        return shoppingList;
    }



    /**
     * 根据条件查询商品
     *
     * @param shoppingDto
     * @return
     */
    @Override
    public List<shopping> getList(SelectShoppingDto shoppingDto) {

        boolean a = false;

        if (shoppingDto.getCid() != null){
            //判断当前操作人的id权限(如果不是商家则返回0)
            Integer i = merchantFeign.permission(shoppingDto.getCid()).getData();

            //权限校验
            if (Objects.equals(i, Permission.ADMIN) || Objects.equals(i, Permission.ORDINARY)){
                a = true;
            }
        }


        //参数校验
        if (shoppingDto.getPage() == null || shoppingDto.getPageSize() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"未传入页码或页数");
        }

        Page<shopping> page = new Page<>(shoppingDto.getPage(), shoppingDto.getPageSize());

        //默认查询
        mocha(shoppingDto , a);

        //构造查询条件
        LambdaQueryWrapper<shopping> wrapper = new LambdaQueryWrapper<>();

        //姓名模糊匹配
        if (!shoppingDto.getName().isEmpty()){
            wrapper.like(shopping::getName , shoppingDto.getName());
        }

        //价格范围查询
        wrapper.between(shopping::getPrice,shoppingDto.getMinPrice(),shoppingDto.getMaxPrice());

        //进价范围查询
        if (a){
            wrapper.between(shopping::getCost,shoppingDto.getMinCost(),shoppingDto.getMaxCost());
        }

        //供货商id查询
        if (shoppingDto.getSource() != null){
            wrapper.eq(shopping::getSource,shoppingDto.getSource());
        }

        //是否上下架
        wrapper.eq(shopping::getExist,shoppingDto.getExist());

        List<shopping> list = page(page, wrapper).getRecords();

        if (!a){
            return list.stream().peek(shopping -> {
                shopping.setCost(0);
            }).toList();
        }

        return list;
    }

    /**
     * 上下架商品
     *
     * @param id
     * @return
     */
    @Override
    public Integer updown(Integer id, Integer shoppingId) {

        //判断操作人id权限
        Integer i = merchantFeign.permission(id).getData();

        if (i == null || i.equals(Permission.NO)){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"权限不够无法上下架商品");
        }

        //判断商品是否存在
        shopping shopping = getById(shoppingId);

        if (shopping == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"传入的商品id错误");
        }

        //上下架
        Integer exist = shopping.getExist();

        if (exist == 0){
            shopping.setExist(1);
        }else {
            shopping.setExist(0);
        }

        updateById(shopping);

        return 1;
    }

    /**
     * 计算商品材料费用
     *
     * @param signSelects
     * @return
     */
    @Override
    public Integer materialsmoney(List<signSelect> signSelects) {
        //总进价
        int count = 0;

        //获取所有商品的id
        ArrayList<Integer> ids = new ArrayList<>();

        //遍历数组
        for (signSelect signSelect : signSelects) {
            Integer id = signSelect.getId();

            ids.add(id);
        }

        //根据商品ids获取所有商品
        List<shopping> shoppingList = listByIds(ids);

        if (shoppingList == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"传入的商品有误");
        }

        for (int i = 0; i < shoppingList.size(); i++) {
            Integer cost = shoppingList.get(i).getCost();
            Integer amount = signSelects.get(i).getAmount();
            count += cost * amount;
        }

        return count;
    }

    /**
     * 根据id查询商品
     *
     * @param shoppingid
     * @return
     */
    @Override
    public shopping getO(Integer shoppingid) {

        if (shoppingid == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"没有传入商品id");
        }

        return getById(shoppingid) ;
    }

    private static void mocha(SelectShoppingDto shoppingDto , boolean a) {
        if (a){
            if (shoppingDto.getMinCost() == null){
                shoppingDto.setMinCost(0);
            }

            if (shoppingDto.getMaxCost() == null){
                shoppingDto.setMaxCost(1000000);
            }
        }

        if (shoppingDto.getMinPrice() == null){
            //设置最小默认查询
            shoppingDto.setMinPrice(0);
        }

        if (shoppingDto.getMaxPrice() == null){
            //设置最大默认查询
            shoppingDto.setMaxPrice(1000000);
        }

        if (shoppingDto.getExist() == null){
            //默认查询上架的商品
            shoppingDto.setExist(1);
        }
    }


    /**
     * 新增参数判断
     * @param addShoppingDto
     */
    private static void pan(AddShoppingDto addShoppingDto) {
        if (addShoppingDto.getName().length() > 50){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"添加的商品名称长度不能大于50");
        }

        //规格校验
        if (addShoppingDto.getSpec().length() >20){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"添加的商品规格长度不能大于20");
        }

        //卖价和进货价校验
        if (addShoppingDto.getPrice() < 0 || addShoppingDto.getCost() < 0){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"卖价和进货价不能为负数");
        }
    }




    /**
     * 校验新增参数
     * @param addShoppingDto
     */
    private static void jiaoyan(AddShoppingDto addShoppingDto) {
        if (addShoppingDto.getCid() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"未传入当前操作人id");
        }

        if (addShoppingDto.getName() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"未传入要添加的商品名称");
        }

        if (addShoppingDto.getSpec() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"未传入要添加的商品规格");
        }

        if (addShoppingDto.getPrice() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"未传入商品的卖价");
        }

        if (addShoppingDto.getCost() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"未传入商品的进价");
        }

        if (addShoppingDto.getSource() == null){
            throw new SandException(AppHttpCodeEnum.PARAM_INVALID,"未传入商品的供货商");
        }
    }


}
